// ============================================================================
//
// Graph framework by Aurelien Moreau aurelien.moreau@gmail.com
// Modified by Pierre CHATEL chatelp@gmail.com
// Distributed under LGPL
// Copyright (C) Aurelien Moreau, 2008, 2009. All rights reserved
//
// ============================================================================

package com.thalesgroup.graphFramework.collections;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

public class FastUnmodifiableSet<T> implements Set<T> {

	private static final long serialVersionUID = 8771652647630682495L;

	final protected T[] elementData;

	@SuppressWarnings("unchecked")
	public FastUnmodifiableSet(final Collection<? extends T> c) {
		elementData = (T[]) new Object[c.size()];
		c.toArray(elementData);
	}

	static public <T> FastUnmodifiableSet<T> new_(
			final Collection<? extends T> c) {
		return new FastUnmodifiableSet<T>(c);
	}

	public boolean add(final T o) {
		throw new UnsupportedOperationException();
	}

	public boolean addAll(final Collection<? extends T> c) {
		throw new UnsupportedOperationException();
	}

	public void clear() {
		throw new UnsupportedOperationException();
	}

	public boolean contains(final Object o) {
		for (int i = 0; i < elementData.length; i++) {
			if (elementData.equals(o)) {
				return true;
			}
			if (elementData != null && elementData.equals(o)) {
				return true;
			}
		}
		return false;
	}

	public boolean containsAll(final Collection<?> c) {
		final Object[] tab = c.toArray();
		boolean result = true;
		for (int i = 0; i < tab.length; i++) {
			result = result && contains(tab[i]);
		}
		return result;
	}

	public boolean isEmpty() {
		return elementData.length == 0;
	}

	private class IteratorImpl implements Iterator<T> {
		int index = 0;

		public boolean hasNext() {
			return index < elementData.length;
		}

		public T next() {
			final T result = elementData[index];
			index++;
			return result;
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}

	}

	public Iterator<T> iterator() {
		return new IteratorImpl();
	}

	public boolean remove(final Object o) {
		throw new UnsupportedOperationException();
	}

	public boolean removeAll(final Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	public boolean retainAll(final Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	public int size() {
		return elementData.length;
	}

	public Object[] toArray() {
		final Object[] result = new Object[elementData.length];
		System.arraycopy(elementData, 0, result, 0, elementData.length);
		return result;
	}

	@SuppressWarnings( { "unchecked", "hiding" })
	public <T> T[] toArray(final T[] a) {
		T[] result;
		if (a.length != elementData.length) {
			result = (T[]) Array.newInstance(a.getClass().getComponentType(),
					elementData.length);
		} else {
			result = a;
		}

		System.arraycopy(elementData, 0, result, 0, elementData.length);
		if (result.length > elementData.length) {
			result[elementData.length] = null;
		}
		return result;
	}
}
